from flask_restx import fields, Resource
from flask_jwt_extended import jwt_required, get_jwt_identity
from .. import db
from ..models import User, UserRole, UserStatus
from . import make_namespace
from flask import request
from ..core import make_response, make_paginated
from flask import current_app


api = make_namespace("02.Users", "用户模块")


user_model = api.model("User", {
	"id": fields.Integer,
	"username": fields.String,
	"email": fields.String,
	"role": fields.String,
	"status": fields.String,
	"is_admin": fields.Boolean,
})


def _require_admin(user: User) -> None:
	if not user or not user.is_admin:
		api.abort(403, "需要管理员权限")


@api.route("")
class UserList(Resource):
	@jwt_required()
	def get(self):
		page_num = int(request.args.get("page", 1))
		page_size = int(request.args.get("page_size", current_app.config.get("PAGE_SIZE", 20)))
		q = User.query.order_by(User.id.desc())
		total = q.count()
		items = [u.to_dict() for u in q.offset((page_num - 1) * page_size).limit(page_size).all()]
		data = make_paginated(items, total, page_num, page_size)
		return make_response(data)

	@jwt_required()
	@api.expect(user_model, validate=False)
	def post(self):
		current_user = User.query.get(int(get_jwt_identity()))
		_require_admin(current_user)
		payload = api.payload or {}
		user = User(
			username=payload.get("username"),
			email=payload.get("email"),
			role=UserRole(payload.get("role", UserRole.active)),
			status=UserStatus(payload.get("status", UserStatus.active)),
			is_admin=bool(payload.get("is_admin", False)),
		)
		# 若未提供密码，设置默认初始密码，便于管理员批量创建后用户首次登录修改
		initial_password = payload.get("password") or "Pass@123"
		user.set_password(initial_password)
		db.session.add(user)
		db.session.commit()
		return make_response(user.to_dict())


@api.route("/<int:user_id>")
class UserDetail(Resource):
	@jwt_required()
	def get(self, user_id: int):
		user = User.query.get_or_404(user_id)
		return make_response(user.to_dict())

	@jwt_required()
	@api.expect(user_model, validate=False)
	def put(self, user_id: int):
		current_user = User.query.get(int(get_jwt_identity()))
		_require_admin(current_user)
		user = User.query.get_or_404(user_id)
		payload = api.payload or {}
		for key in ["username", "email"]:
			if key in payload and payload[key]:
				setattr(user, key, payload[key])
		if "role" in payload:
			user.role = UserRole(payload["role"]) if payload["role"] else user.role
		if "status" in payload:
			user.status = UserStatus(payload["status"]) if payload["status"] else user.status
		if "is_admin" in payload:
			user.is_admin = bool(payload["is_admin"])
		if "password" in payload and payload["password"]:
			user.set_password(payload["password"])
		db.session.commit()
		return make_response(user.to_dict())

	@jwt_required()
	def delete(self, user_id: int):
		current_user = User.query.get(int(get_jwt_identity()))
		_require_admin(current_user)
		user = User.query.get_or_404(user_id)
		db.session.delete(user)
		db.session.commit()
		return make_response({"message": "已删除"})


